]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
extensionSystem: Load extensions as modules
authorFlorian Müllner <fmuellner@gnome.org>
Thu, 1 Jun 2023 22:47:22 +0000 (00:47 +0200)
committerMarge Bot <marge-bot@gnome.org>
Thu, 6 Jul 2023 18:41:29 +0000 (18:41 +0000)
Continue the move to ESM by loading modules dynamically with
the standard import() expression, rather than by installing a
custom (legacy) importer.

This is a breaking change that affects all extensions, as they
now need to explicitly export the expected symbols.

As we are already breaking all extensions, take that opportunity
and remove support for the individual entry points: Using a
class with enable()/disable() methods has been the recommended
pattern for a long time, it is now the only entry point.

Instead of instantiating the class from an `init()` function,
the class must now be exported as default to be recognized.

Additionally, we no longer install an importer on the extension
object, so extensions that consist of more than one file MUST
import those files as modules now.

There will be a second breaking change for extensions when
gnome-shell's own code is ported to ESM, so most extension
developers will likely want to wait until the port is complete
before starting to port their extensions.

Based on a commit from Evan Welsh.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2795>

js/ui/extensionSystem.js

index 9c36a827520f3fff60f28911c2d1771d727bf39e..84c85f0424d44cb6f89eaed6f7b72983ac998781 100644 (file)
@@ -512,36 +512,25 @@ var ExtensionManager = class extends Signals.EventEmitter {
         let extensionModule;
         let extensionState = null;
 
-        // TODO: This function does not have an async operation but when ESM is
-        // merged there will be a dynamic import here instead of `installImporter`.
-        await 0;
-
-        ExtensionUtils.installImporter(extension);
-
-        // Extensions can only be imported once, so add a property to avoid
-        // attempting to re-import an extension.
-        extension.isImported = true;
-
         try {
-            extensionModule = extension.imports.extension;
+            extensionModule = await import(extensionJs.get_uri());
+
+            // Extensions can only be imported once, so add a property to avoid
+            // attempting to re-import an extension.
+            extension.isImported = true;
         } catch (e) {
             this.logExtensionError(uuid, e);
             return false;
         }
 
-        if (extensionModule.init) {
-            try {
-                extensionState = await extensionModule.init(extension);
-            } catch (e) {
-                this.logExtensionError(uuid, e);
-                return false;
-            }
+        try {
+            extensionState = new extensionModule.default(extension.metadata);
+        } catch (e) {
+            this.logExtensionError(uuid, e);
+            return false;
         }
 
-        if (!extensionState)
-            extensionState = extensionModule;
         extension.stateObj = extensionState;
-
         extension.state = ExtensionState.DISABLED;
         this.emit('extension-loaded', uuid);
         return true;